﻿using Microsoft.Xna.Framework;
using DrawableObjects.Actors;
using System;

namespace Sirian.DrawableObject.Actors
{
    /// <summary>
    /// Represents a rectangular area in the game world
    /// </summary>
    public class Bounding
    {
        public Vector2 upperLeft
        {
            get;
            private set;
        }

        public float width
        {
            get;
            private set;
        }
        public float height
        {
            get;
            private set;
        }


        // if true, actos are not allowed to cross the borders of the rectangle
        public bool isBinding
        {
            get;
            private set;
        }

        public void moveBounding(Vector2 delta)
        {
            upperLeft += delta;
        }

        public Bounding(Vector2 upperLeft, float width, float height, bool isBinding)
        {
            this.upperLeft = upperLeft;
            this.width = width;
            this.height = height;
            this.isBinding = isBinding;
        }

        public bool isWithinBounding(Vector2 gamePosition, float radius)
        {
            bool isWithinBounding = gamePosition.X + radius - upperLeft.X <= width;
            isWithinBounding &= gamePosition.X - radius >= upperLeft.X;
            isWithinBounding &= gamePosition.Y + radius - upperLeft.Y <= height;
            isWithinBounding &= gamePosition.Y - radius >= upperLeft.Y;
            return isWithinBounding;
        }


        /// <summary>
        /// Gets the closest point a circle can be moved near the borders within a rectangle without leaving them
        /// </summary>
        public Vector2 getClosestPointWithin(Vector2 gamePosition, Vector2 direction, float radius)
        {
            Vector2 relativePosition = Vector2.Subtract(gamePosition, upperLeft);
            float xTranslation = 0f;
            float yTranslation = 0f;
            float temp;
            float effectiveRadius = radius + 1;
            if (direction.X > 0)
            {
                temp = width - relativePosition.X;
                if (direction.X + effectiveRadius <= temp)
                {
                    xTranslation = direction.X;
                }
                else
                {
                    xTranslation = temp - effectiveRadius;
                }
            }
            else if (direction.X <= 0)
            {
                temp = relativePosition.X;
                if (temp + direction.X >= effectiveRadius)
                {
                    xTranslation = direction.X;
                }
                else
                {
                    xTranslation = effectiveRadius - temp;
                }
            }
            if (direction.Y > 0)
            {
                temp = height - relativePosition.Y;
                if (direction.Y + effectiveRadius <= temp)
                {
                    yTranslation = direction.Y;
                }
                else
                {
                    yTranslation = temp - effectiveRadius;
                }
            }
            else if (direction.Y <= 0)
            {
                temp = relativePosition.Y;
                if (temp + direction.Y >= effectiveRadius)
                {
                    yTranslation = direction.Y;
                }
                else
                {
                    yTranslation = effectiveRadius - temp;
                }
            }
            Vector2 returnPoint = new Vector2(gamePosition.X + xTranslation, gamePosition.Y + yTranslation);
            return returnPoint;
        }
    }  
}
